﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CayleyTree
{
    public partial class Form1 : Form
    {
        private Graphics graphics;
        private float x;
        private float y;
        //设置各参数初始值
        double rThAngle = 30 * Math.PI / 180;
        double lThAngle = 20 * Math.PI / 180;
        double rPerRate = 0.6;
        double lPerRate = 0.7;
        Pen pen;

        public Form1()
        {
            InitializeComponent();
            x = this.Width;
            y = this.Height;
            setTag(this);
            this.pen_color.SelectedIndex = 0;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        /**
         * (x0,y0)起点 n递归深度 leng主干长度
         */
        private void drawCayleyTree(int n, double x0, double y0, double leng, double th)
        {
            if (n == 0)
            {
                return;
            }

            var x1 = x0 + leng * Math.Cos(th);
            var y1 = y0 + leng * Math.Sin(th);

            drawLine(x0, y0, x1, y1);

            if ((int)x0 == (int)x1 && (int)y0 == (int)y1)
            {
                return;
            }

            drawCayleyTree(n - 1, x1, y1, rPerRate * leng, th + rThAngle);
            drawCayleyTree(n - 1, x1, y1, lPerRate * leng, th - lThAngle);
        }

        private void drawLine(double x0, double y0, double x1, double y1)
        {
            graphics.DrawLine(pen, (int)x0, (int)y0, (int)x1, (int)y1);
        }

        private void pen_SelectedIndexChanged(object sender, EventArgs e)
        {
            Pen[] pens = { Pens.Black, Pens.Yellow, Pens.Blue, Pens.Green, Pens.Red, Pens.Brown};
            pen = pens[pen_color.SelectedIndex];
        }

        private void n_Scroll(object sender, EventArgs e)
        {
            label1.Text = "递归深度:" + n.Value;
        }

        private void leng_Scroll(object sender, EventArgs e)
        {
            label2.Text = "主干长度:" + leng.Value;
        }

        private void per1_Scroll(object sender, EventArgs e)
        {
            rPerRate = (double)per1.Value / 10;
            label3.Text = "右分支长度比" + rPerRate;
        }

        private void per2_Scroll(object sender, EventArgs e)
        {
            lPerRate = (double)per2.Value / 10;
            label4.Text = "左分支长度比" + lPerRate;
        }

        private void th1_Scroll(object sender, EventArgs e)
        {
            rThAngle = (int)th1.Value * Math.PI / 180;
            label5.Text = "右分支角度" + th1.Value + "°";
        }

        private void th2_Scroll(object sender, EventArgs e)
        {
            lThAngle = (int)th2.Value * Math.PI / 180;
            label6.Text = "左分支角度" + th2.Value + "°";
        }

        private void draw_btn_Click(object sender, EventArgs e)
        {
            if (graphics == null) graphics = this.CreateGraphics();
            graphics.Clear(BackColor);
            drawCayleyTree(n.Value, this.Width / 2 + 80, this.Height, (double)leng.Value, -Math.PI / 2);
        }

        private void setTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    setTag(con);
                }
            }
        }
        private void setControls(float newx, float newy, Control cons)
        {
            //遍历窗体中的控件，重新设置控件的值
            foreach (Control con in cons.Controls)
            {
                //获取控件的Tag属性值，并分割后存储字符串数组
                if (con.Tag != null)
                {
                    string[] mytag = con.Tag.ToString().Split(new char[] { ';' });
                    //根据窗体缩放的比例确定控件的值
                    con.Width = Convert.ToInt32(System.Convert.ToSingle(mytag[0]) * newx);//宽度
                    con.Height = Convert.ToInt32(System.Convert.ToSingle(mytag[1]) * newy);//高度
                    con.Left = Convert.ToInt32(System.Convert.ToSingle(mytag[2]) * newx);//左边距
                    con.Top = Convert.ToInt32(System.Convert.ToSingle(mytag[3]) * newy);//顶边距
                    Single currentSize = System.Convert.ToSingle(mytag[4]) * newy;//字体大小
                    con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                    if (con.Controls.Count > 0)
                    {
                        setControls(newx, newy, con);
                    }
                }
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / x;
            float newy = (this.Height) / y;
            setControls(newx, newy, this);
        }
    }
}
